from django.shortcuts import render
from rest_framework.views import APIView
from .models import User
from rest_framework.response import Response

# Create your views here.

# APIView
# GenericAPIView
# ListAPIView,RetrieveAPIView

# 是否用到序列化器
# 此视图没有用到序列化器,所以 不需要列表或者详情视图的支持,所以选项APIView

"""用户名唯一性验证"""


class RegisterUserNameView(APIView):
    """
    GET      /users/usernames/(?P<username>\w{5,20})/count/

    当光标移动之后,前段需要将用户名发送给我们后端,我们后端根据前段提交的用户名进行数据的查询
    如果数据存在 则表示已经注册
    如果数据不存在 则表示没有注册
    """

    def get(self, request, username):
        """
        我们后端根据前段提交的用户名进行数据的查询
        查询的数量
        如果数据存在 则表示已经注册
        如果数据不存在 则表示没有注册
        """
        # 端根据前段提交的用户名进行数据的查询
        count = User.objects.filter(username=username).count()

        # 我们需要返回
        # 1:表示已经注册
        # 0: 没有注册
        context = {
            'count': count,
            'name': username
        }

        #
        return Response(context)


"""手机号唯一性验证"""


class RegisterPhoneCountAPIView(APIView):
    """
    查询手机号的个数
    GET: /users/phones/(?P<mobile>1[345789]\d{9})/count/
    """

    def get(self, request, mobile):
        # 通过模型查询获取手机号个数
        count = User.objects.filter(mobile=mobile).count()
        # 组织数据
        context = {
            'count': count,
            'phone': mobile
        }

        return Response(context)


"""用户注册"""
# 方是一：
from rest_framework.views import APIView
from .serializers import RegisterUserSerializer


class RegisterUserView(APIView):
    """
        分析：POST /users/
            用户点击注册按钮，前端需要把用户名，密码，手机号传递给后端，后续入库
            另外前端还需要把确认密码，短信验证码，和是否同意协议传递给后端，用于验证(其中图片验证主要是用于短信的接收，并且已经验证过，所以注册的时候不需要再重复验证了)
            1.	接收前端传递过来的用户名，密码，手机号，另外还要接收确认密码，短信验证码，和是否同意协议
            2.	对数据进行验证
            3.	验证通过则保存到数据库
    """

    def post(self, request):
        serializer = RegisterUserSerializer(data=request.data)

        serializer.is_valid(raise_exception=True)

        serializer.save()

        return Response(serializer.data)


"""用户中心"""
from rest_framework.generics import GenericAPIView
from .serializers import UserInfoSerializer
from rest_framework.permissions import IsAuthenticated

# class UserInfoView(GenericAPIView):
#     """
#         分析：
#             1.	用户必须是登录状态才能访问跟人中心页面
#             2.	获取用户的信息，用户的信息缺少一个邮件激活状态的字段
#             3.	获取用户信息，用户信息在模型中，我们需要将模型转化成json(序列化过程)
#     """
#     permission_classes = [IsAuthenticated]
#
#     def get(self,request):
#
#         user = request.user
#
#         serializer = UserInfoSerializer(instance=user)
#
#         return Response(serializer.data)


"""获取用户信息的第二种方式"""
from rest_framework.generics import RetrieveAPIView


class UserInfoView(RetrieveAPIView):
    permission_classes = [IsAuthenticated]

    serializer_class = UserInfoSerializer

    def get_object(self):
        return self.request.user


"""邮件激活"""
from rest_framework.generics import UpdateAPIView
from .serializers import EmailSerializer


class EmailView(UpdateAPIView):
    """
        分析：
        １．我们要求前端把用户的邮箱发送过来
        ２．我们后端需要把这个信息保存起来，保存在指定的记录中(更新数据)
            这个接口必须传递用户信息，这个接口只能是登陆用户才能访问
        ３．邮件信息保存之后，我们需要发送激活邮件
            如何发邮件，邮件信息如何生成
    """

    # 发送邮件必须是登陆用户才可以发送
    permission_classes = [IsAuthenticated]

    # 序列化器对象
    serializer_class = EmailSerializer

    # 父类的 get_object 是通过 pk来获取数据的,但是它不能满足我们的需求
    # 我们制定 get_object 就是获取指定用户信息,所以重写,直接将 request.user返回
    def get_object(self):
        return self.request.user


"""激活邮件，改变激活状态"""
from rest_framework import status


class EmailActiveView(APIView):
    """
        分析：/users/emails/verification/
        １．前面已经生成了激活邮件，并发送成功了，用户在邮件箱只需要点击激活链接，会发送一个ＧＥＴ请求，请求中会以查询字符串的形式携带token信息
        ２．我们后端需要获取token信息，并解析出来，找到对应的user信息
        ３．改变user的邮件激活状态
    """

    def get(self, request):

        token = request.query_params.get("token")
        if token is None:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        # 通过token 解析出user信息
        user = User.generic_user_by_token(token)

        if user is None:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        user.email_active = True
        user.save()

        return Response({"message": "ok"})


# """获取所有的数据列表"""
# from rest_framework.generics import GenericAPIView
# from .serializers import UserListSerializer
# class UserListView(GenericAPIView):
#
#     queryset = User.objects.all()
#
#     serializer_class = UserListSerializer
#
#     def get(self,request):
#
#         users = self.get_queryset()
#         serializer = self.get_serializer(users,many=True)
#
#         return Response(serializer.data)
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet
from .serializers import AddressSerializer


class AddressViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, mixins.UpdateModelMixin, GenericViewSet):
    """
    用户地址新增与修改
    list GET: /users/addresses/
    create POST: /users/addresses/
    destroy DELETE: /users/addresses/
    action PUT: /users/addresses/pk/status/
    action PUT: /users/addresses/pk/title/
    """

    # 制定序列化器
    serializer_class = AddressSerializer
    # 添加用户权限
    permission_classes = [IsAuthenticated]

    # 由于用户的地址有存在删除的状态,所以我们需要对数据进行筛选
    def get_queryset(self):
        return self.request.user.addresses.filter(is_deleted=False)

    def create(self, request, *args, **kwargs):
        """
        保存用户地址数据
        """
        count = request.user.addresses.count()
        if count >= 20:
            return Response({'message': '保存地址数量已经达到上限'}, status=status.HTTP_400_BAD_REQUEST)

        return super().create(request, *args, **kwargs)

    def list(self, request, *args, **kwargs):
        """
        获取用户地址列表
        """
        # 获取所有地址
        queryset = self.get_queryset()
        # 创建序列化器
        serializer = self.get_serializer(queryset, many=True)
        user = self.request.user
        # 响应
        return Response({
            'user_id': user.id,
            'default_address_id': user.default_address_id,
            'limit': 20,
            'addresses': serializer.data,
        })

    def destroy(self, request, *args, **kwargs):
        """
        处理删除
        """
        address = self.get_object()

        # 进行逻辑删除
        address.is_deleted = True
        address.save()

        return Response(status=status.HTTP_204_NO_CONTENT)


from rest_framework.decorators import action
from .serializers import AddressTitleSerializer


@action(methods=['put'], detail=True)
def title(self, request, pk=None, address_id=None):
    """
    修改标题
    """
    address = self.get_object()
    serializer = AddressTitleSerializer(instance=address, data=request.data)
    serializer.is_valid(raise_exception=True)
    serializer.save()
    return Response(serializer.data)


@action(methods=['put'], detail=True)
def status(self, request, pk=None, address_id=None):
    """
    设置默认地址
    """
    address = self.get_object()
    request.user.default_address = address
    request.user.save()
    return Response({'message': 'OK'}, status=status.HTTP_200_OK)


from .serializers import UserBrowsingHistorySerializer
from rest_framework.generics import GenericAPIView

"""用户浏览记录"""
from goods.models import SKU
from .serializers import SKUSerialzier
from django_redis import get_redis_connection
class UserBrowsingHistoryView(GenericAPIView):
    """
        分析：用户浏览商品时，需要提交POST请求，获取浏览的历史记录需要使用GET请求　　POST /users/browerhistories/
        １．未登录的用户浏览历史记录保存在cookie中，登陆的用户历史浏览记录保存在redis中(必须是登陆用户)
        ２．保存在服务端的redis数据库中
        ３．redis中需要保存的数据时sku_id，保存的格式时list(用户保存数据在list中的时候，需要根据浏览的时间进行排序)
        ４．用户在浏览之前浏览过的商品的时候，需要在数据库中查询出之前有没有浏览记录，如果有则删掉久的浏览记录，再将新的浏览记录保存在redis中的list表中，那样可以达到一个排序的效果
    """
    permission_classes = [IsAuthenticated]
    serializer_class = UserBrowsingHistorySerializer

    def post(self, request):
        serializer = self.get_serializer(data=request.data)

        serializer.is_valid(raise_exception=True)

        serializer.save()

        return Response(serializer.data)


    def get(self,request):
        # 获取redis中的数据sku_id
        redis_conn = get_redis_connection('history')
        # 获取数据,获取最后浏览的５条数据
        redis_ids = redis_conn.lrange("history_%s"%request.user.id,0,5)
        # 查询出这５条数据商品信息
        # skus = SKU.objects.filter(id__in=redis_ids)
        skus = []
        for sku_id in redis_ids:
            sku = SKU.objects.get(pk=sku_id)
            skus.append(sku)

        serializer = SKUSerialzier(instance=skus,many=True)

        return Response(serializer.data)

from rest_framework_jwt.views import ObtainJSONWebToken
from carts.utils import merge_cart_cookie_to_redis

class UserAuthorizationView(ObtainJSONWebToken):

    def post(self, request):
        # 调用jwt扩展的方法，对用户登录的数据进行验证
        response = super().post(request)

        # 如果用户登录成功，进行购物车数据合并
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            # 表示用户登录成功
            user = serializer.validated_data.get("user")
            # 合并购物车
            #merge_cart_cookie_to_redis(request, user, response)
            response = merge_cart_cookie_to_redis(request, user, response)

        return response